package com.power.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.power.constant.BusinessEnum;
import com.power.domain.Basket;
import com.power.domain.Sku;
import com.power.ex.handle.BussinessException;
import com.power.feign.BasketProdFeign;
import com.power.mapper.BasketMapper;
import com.power.model.CartItem;
import com.power.model.Result;
import com.power.model.ShopCart;
import com.power.service.BasketService;
import com.power.util.AuthUtils;
import com.power.vo.CartTotalAmount;
import com.power.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author dingchunlin
* @description 针对表【basket(购物车)】的数据库操作Service实现
* @createDate 2024-07-10 15:12:13
*/
@Service
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket> implements BasketService{

    @Autowired
    private BasketMapper basketMapper;

    @Autowired
    private BasketProdFeign basketProdFeign;

    /**
     * 根据openId查询购物车中商品数量
     * @param openId 用户openId
     * @return 购物车中商品数量
     */
    @Override
    public Integer queryMemberBasketProdCount(String openId) {
        return basketMapper.queryMemberBasketProdCount(openId);
    }

    /**
     * 根据openId查询购物车信息
     * @return 购物车信息
     */
    @Override
    public CartVo queryMemberCartVo() {
        // 获取用户信息
        String openId = AuthUtils.getMemberOpenId();
        // 创建购物车对象
        CartVo cartVo = new CartVo();
        // 查询购物车信息
        List<Basket> basketList = basketMapper.selectList(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getOpenId, openId));
        // 判断是否有数据
        if (CollectionUtil.isEmpty(basketList) || basketList.size() == 0){
            return cartVo;
        }
        // 获取购物车中的skuId集合
        List<Long> skuIdList = basketList.stream().map(Basket::getSkuId)
                .distinct().collect(Collectors.toList());
        // 远程调用：根据skuId集合查询商品信息
        Result<List<Sku>> result = basketProdFeign.getSkuListByIds(skuIdList);
        if (result.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())){
            throw new BussinessException("远程调用：根据skuId集合查询商品信息失败");
        }
        // 获取商品sku信息
        List<Sku> skuList = result.getData();
        // 创建购物车店铺对象集合
        List<ShopCart> shopCartList = new ArrayList<>();
        // 遍历购物车信息
        basketList.forEach(basket -> {
            // 判断当前购物车记录的店铺是否已经存在
            List<ShopCart> oneShopCart = shopCartList.stream()
                    .filter(shopCart -> shopCart.getShopId().equals(basket.getShopId()))
                    .collect(Collectors.toList());
            // 判断是否有数据
            if (CollectionUtil.isEmpty(oneShopCart) || oneShopCart.size() == 0) {
                // 创建新的店铺对象
                ShopCart shopCart = new ShopCart();
                // 设置购物车商品条目对象集合
                List<CartItem> cartItemList = new ArrayList<>();
                // 设置购物车商品条目
                CartItem cartItem = new CartItem();
                // 进行赋值
                cartItem.setBasketId(basket.getBasketId());
                cartItem.setProdId(basket.getProdId());
                cartItem.setSkuId(basket.getSkuId());
                cartItem.setProdCount(basket.getProdCount());
                // 根据skuId过滤sku数据
                Sku sku1 = skuList.stream()
                        .filter(sku -> sku.getSkuId().equals(basket.getSkuId()))
                        .collect(Collectors.toList()).get(0);
                // 设置商品信息
                BeanUtils.copyProperties(sku1, cartItem);
                // 设置购物车商品条目集合
                cartItemList.add(cartItem);
                // 设置店铺信息
                shopCart.setShopId(basket.getShopId());
                shopCart.setShopCartItems(cartItemList);
                shopCartList.add(shopCart);
            }else {
                // 店铺已经存在，直接添加购物车商品条目
                ShopCart shopCart = oneShopCart.get(0);
                // 获取购物车对象之前的商品条目集合
                List<CartItem> cartItemList = shopCart.getShopCartItems();
                // 将新的购物车商品条目添加到集合中
                CartItem cartItem = new CartItem();
                // 进行赋值
                cartItem.setBasketId(basket.getBasketId());
                cartItem.setProdId(basket.getProdId());
                cartItem.setSkuId(basket.getSkuId());
                cartItem.setProdCount(basket.getProdCount());
                // 根据skuId过滤sku数据
                Sku sku1 = skuList.stream()
                        .filter(sku -> sku.getSkuId().equals(basket.getSkuId()))
                        .collect(Collectors.toList()).get(0);
                // 设置商品信息
                BeanUtils.copyProperties(sku1, cartItem);
                cartItemList.add(cartItem);
                // 进行赋值
                shopCart.setShopCartItems(cartItemList);
            }
        });
        cartVo.setShopCarts(shopCartList);
        return cartVo;
    }

    /**
     * 计算会员选中购物车中商品的总价
     * @param basketIds 选中的购物车商品id
     * @return 购物车商品总价
     */
    @Override
    public CartTotalAmount calculateMemberCheckedBasketTotalAmount(List<Long> basketIds) {
        // 创建购物车商品总价对象
        CartTotalAmount cartTotalAmount = new CartTotalAmount();
        // 判断用户是否选中购物车商品
        if (CollectionUtil.isEmpty(basketIds) || basketIds.size() == 0){
            return cartTotalAmount;
        }
         // 根据basketIds查询购物车信息
        List<Basket> basketList = basketMapper.selectBatchIds(basketIds);
        // 从购物车集合中获取skuId集合
        List<Long> skuIdList = basketList.stream().map(Basket::getSkuId)
                .distinct().collect(Collectors.toList());
        // 远程调用：根据skuId集合查询商品信息
        Result<List<Sku>> result = basketProdFeign.getSkuListByIds(skuIdList);
        if (result.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())){
            throw new BussinessException("远程调用：根据skuId集合查询商品信息失败");
        }
        // 获取商品sku信息
        List<Sku> skuList = result.getData();
        // 创建所有单个商品的总金额集合
        List<BigDecimal> oneSkuTotalAmounts = new ArrayList<>();
        // 循环购物车信息，计算商品总价
        basketList.forEach(basket -> {
            // 获取购买的数量
            Integer prodCount = basket.getProdCount();
            // 根据skuId过滤sku数据
            Sku sku = skuList.stream()
                    .filter(sku1 -> sku1.getSkuId().equals(basket.getSkuId()))
                    .collect(Collectors.toList()).get(0);
            // 获取商品单价
            BigDecimal price = sku.getPrice();
            // 计算单个商品的总价
            BigDecimal oneProdTotalAmount = price.multiply(new BigDecimal(prodCount));
            // 添加到集合中
            oneSkuTotalAmounts.add(oneProdTotalAmount);
        });
        // 计算所有商品的总价
        BigDecimal allSkuTotalAmount = oneSkuTotalAmounts.stream().reduce(BigDecimal::add).get();
        // 设置总价
        cartTotalAmount.setTotalMoney(allSkuTotalAmount);
        cartTotalAmount.setFinalMoney(allSkuTotalAmount);
        // 运费：商品总金额超过99免运费，否则6元
        if (allSkuTotalAmount.compareTo(new BigDecimal(99)) == -1){
            cartTotalAmount.setTransMoney(new BigDecimal(6));
            cartTotalAmount.setFinalMoney(allSkuTotalAmount.add(new BigDecimal(6)));
        }
        return cartTotalAmount;
    }

    /**
     * 修改购物车商品数量
     * @param basket 购物车商品信息
     * @return 修改结果
     */
    @Override
    public Boolean changeMemberBasketItem(Basket basket) {
        // 获取用户信息
        String openId = AuthUtils.getMemberOpenId();
        // 根据basketId查询购物车信息
        Basket oldBasket = basketMapper.selectOne(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getProdId, basket.getProdId())
                .eq(Basket::getShopId, basket.getShopId())
                .eq(Basket::getSkuId, basket.getSkuId())
                .eq(Basket::getOpenId, openId));
        // 判断是否有数据
        if (ObjectUtil.isEmpty(oldBasket)){
            // 新增购物车商品
            basket.setOpenId(openId);
            basket.setCreateTime(new Date());
            return basketMapper.insert(basket) > 0;
        }else {
            // 获取原有的数量
            Integer prodCount = oldBasket.getProdCount();
            // 判断是新增还是减少
            if (basket.getProdCount().equals(1)){
                oldBasket.setProdCount(prodCount + 1);
            }else {
                oldBasket.setProdCount(prodCount - 1);
            }
            return basketMapper.updateById(oldBasket) > 0;
        }

    }
}




